
<template>
  <el-dialog v-dialogDrag :visible.sync="currentDialogVisible" :top="common.getDialogTop()" title="查询条件设置" class="dialog-container" width="1400px" append-to-body>
    <el-container class="designer-container" @keydown.native.f2="createBaseVue('json')" @keydown.native.f3="createBaseVue('save')">
      <el-aside width="250px" class="components-list">
        <el-collapse accordion>
          <el-collapse-item title="基础字段">
            <draggable :list="basicComponents" :options="{group:{ name:'people', pull:'clone',put:false},sort:false, ghostClass: 'ghost'}" :move="handleMove" tag="ul" @end="handleMoveEnd" @start="handleMoveStart">
              <li v-for="(item, index) in basicComponents" :key="index" class="form-edit-widget-label">
                <a>
                  <i :class="item.icon"></i>
                  <span>{{ item.label }}</span>
                </a>
              </li>
            </draggable>
          </el-collapse-item>
          <el-collapse-item title="布局字段">
            <draggable :list="layoutComponents" :options="{group:{ name:'people', pull:'clone',put:false},sort:false, ghostClass: 'ghost'}" :move="handleMove" tag="ul" @end="handleMoveEnd" @start="handleMoveStart">
              <li v-for="(item, index) in layoutComponents" :key="index" class="form-edit-widget-label data-grid">
                <a>
                  <i :class="item.icon"></i>
                  <span>{{ item.label }}</span>
                </a>
              </li>
            </draggable>
          </el-collapse-item>
        </el-collapse>
      </el-aside>

      <el-container class="center-container" direction="vertical">
        <div :class="{'widget-empty': widgetFormData.editorOptions.fields.length == 0}" style="min-height:600px">
          <widget-form ref="widgetForm" :data="widgetFormData" :select.sync="widgetFormSelect" :config-type.sync="configType"></widget-form>
        </div>
      </el-container>

      <el-aside class="widget-config-container">
        <el-container>
          <el-header height="45px" class="param-header">
            <div :class="{active: configTab=='widget'}" class="config-tab" @click="handleConfigSelect('widget')">字段属性</div>
            <div :class="{active: configTab=='form'}" class="config-tab" @click="handleConfigSelect('form')">表单属性</div>
          </el-header>
          <el-main class="config-content">
            <el-scrollbar v-show="configTab=='widget'" :noresize="false" :native="false" wrap-class="config scrollbar-wrap">
              <component :is="configType" :data="widgetFormSelect" :data-options="widgetFormData.dataOptions" :basic-components="basicComponents"></component>
            </el-scrollbar>
            <el-scrollbar v-show="configTab=='form'" :noresize="false" :native="false" wrap-class="config scrollbar-wrap">
              <form-config :data="widgetFormData" :editor-config="widgetFormData.editorOptions.config" :data-options="widgetFormData.dataOptions"></form-config>
            </el-scrollbar>
          </el-main>
        </el-container>
      </el-aside>

      <cus-dialog ref="jsonPreview" :visible="jsonVisible" title="生成JSON并保存Vue文件" width="800px" form @on-close="jsonVisible = false">
        <div id="jsoneditor" style="height: 400px;width: 100%;">{{ moduleNode.vueData }}</div>
        <template slot="action">
          <el-button data-clipboard-target=".ace_text-input" @dblclick.native="$message.success('复制成功');">双击复制</el-button>
          <el-button :loading="createLoading" type="primary" data-clipboard-target=".ace_text-input" @click.native="createBaseVue('jsoneditor')">保存查询设计</el-button>
        </template>
      </cus-dialog>

    </el-container>

    <span slot="footer" class="dialog-footer">
      <el-button @click="currentDialogVisible = false">关闭</el-button>
      <el-button type="primary" @click="handleGenerateJson()">查看代码</el-button>
      <el-button type="primary" @click="createBaseVue()">保存</el-button>
    </span>
  </el-dialog>
</template>

<script>
import eventBus from "@/utils/eventBus";
import Draggable from "vuedraggable";
import WidgetConfig from "./WidgetConfig";
import FormConfig from "./FormConfig";
import WidgetForm from "./WidgetForm";
import CusDialog from "./CusDialog";
import Sticky from "@/components/Sticky";
import Vue from "vue";
Vue.config.keyCodes.f2 = 113;
Vue.config.keyCodes.f3 = 114;
import { basicComponents, layoutComponents } from "./componentsConfig.js";
import { loadJs } from "./util/index.js";

export default {
  components: {
    Draggable,
    WidgetConfig,
    FormConfig,
    WidgetForm,
    CusDialog,
    Sticky,
  },
  props: {
    designer: {
      type: Object,
      default: () => {
        return {};
      },
    },
    visible: {
      type: Boolean,
      default: false,
    },
  },
  data() {
    return {
      basicComponents,
      layoutComponents,
      // 当前配置参数设置组件
      configType: "WidgetConfig",
      // 模块字段信息
      moduleNode: {},
      // 设计器数据结构
      widgetFormData: {
        // 数据加载及保存参数
        dataOptions: {
          projectName: "BasicInfo",
          tableView: "Base_Provider",
          idField: "provider_Id",
          router: "/basic/asset/provider",
          idValue: 0,
          codeRegular: "providerCode", // 自动编码字段
          linkColumn: null, // 链接到弹出编辑窗口的字段
          menu_Id: 428,
          pageIndex: 1,
          pageSize: 15,
          total: 0,
          sortName: { provider_Id: "DESC" },
          showActionField: true, // 列表页显示Action列
        },

        // 编辑器对话框参数
        editorOptions: {
          fields: [],
          config: {
            labelWidth: "80px", // 标签文字宽度
            labelPosition: "right", // 标签位置
            top: "3vh", // 对话框底部距离
            width: "1200px", // 对话框宽度
            visible: false, // 是否显示添加实验室对话框
            disabled: false, // 是否禁用
            title: null, // 对话框标题
            action: "add", // 接收值为：add、edit
            formInline: false, // 行内表单
            saveButtonText: "保存",
          },
        },
      },

      // 设计器默认数据结构
      widgetFormDataDefault: {
        // 数据加载及保存参数
        dataOptions: {
          projectName: "BasicInfo",
          tableView: "Base_Provider",
          idField: "provider_Id",
          router: "/basic/asset/provider",
          idValue: 0,
          codeRegular: "providerCode", // 自动编码字段
          linkColumn: null, // 链接到弹出编辑窗口的字段
          menu_Id: 428,
          pageIndex: 1,
          pageSize: 15,
          total: 0,
          sortName: { provider_Id: "DESC" },
          showActionField: true, // 列表页显示Action列
        },

        // 编辑器对话框参数
        editorOptions: {
          fields: [],
          config: {
            labelWidth: "80px", // 标签文字宽度
            formWidth: "auto", // 表单宽度
            labelPosition: "right", // 标签位置
            top: "3vh", // 对话框底部距离
            width: "1200px", // 对话框宽度
            visible: false, // 是否显示添加实验室对话框
            disabled: false, // 是否禁用
            title: "资产分类",
            action: "add", // 接收值为：add、edit
            formInline: false, // 行内表单
            saveButtonText: "保存",
          },
        },
      },
      configTab: "widget",
      widgetFormSelect: null, // 选中项
      jsonVisible: false,
      createLoading: false, // 创建页面loading
    };
  },
  computed: {
    // 显示窗口
    currentDialogVisible: {
      get: function () {
        return this.visible;
      },
      set: function (val) {
        this.$emit("update:visible", val);
      },
    },
  },
  watch: {
    widgetFormData: {
      deep: true,
      handler: function (val) {
        if (this.moduleNode) {
          this.moduleNode.vueData = JSON.stringify(val, null, 2);
        }
      },
    },
    widgetFormSelect: {
      handler(val) {},
      deep: true,
    },
  },
  mounted() {
    loadJs(
      "https://auod-beijing.oss-cn-beijing.aliyuncs.com/ace/src-min-noconflict/ace.js"
    );
    this.bindEvent();
  },
  methods: {
    // 事件处理
    bindEvent() {
      // 左侧导航改变事件
      eventBus.$on("bi-left-node-change", ({ node, data }) => {
        this.moduleNode = data;
        if (this.moduleNode.vueData) {
          this.widgetFormData = JSON.parse(this.moduleNode.vueData);
        } else {
          this.widgetFormData = this.common.deepCopy(
            this.widgetFormDataDefault
          );
        }
      });
    },
    handleConfigSelect(value) {
      this.configTab = value;
    },
    handleMoveEnd(evt) {
      // console.log("end", evt);
    },
    handleMoveStart({ oldIndex }) {
      // console.log("start", oldIndex, this.basicComponents);
    },
    handleMove() {
      return true;
    },
    reset() {
      var data = this.moduleNode;
      this.widgetFormData = Object.assign({}, this.widgetFormDataDefault, {
        dataOptions: {
          projectName: data.projectName,
          tableView: data.tableView,
          idField: data.idField,
          router: null,
          idValue: 0,
          codeRegular: data.codeRegular, // 自动编码字段
          linkColumn: data.linkColumn, // 链接到弹出编辑窗口的字段
          menu_Id: null,
          pageIndex: 1,
          pageSize: 15,
          total: 0,
          sortName: data.sortName,
          showActionField: true, // 列表页显示Action列
        },
        // 编辑器对话框参数
        editorOptions: {
          fields: [],
          config: {
            labelWidth: "80px", // 标签文字宽度
            labelPosition: "right", // 标签位置
            top: "3vh", // 对话框底部距离
            width: "1200px", // 对话框宽度
            visible: false, // 是否显示添加实验室对话框
            disabled: false, // 是否禁用
            title: null, // 对话框标题
            action: "add", // 接收值为：add、edit
            formInline: false, // 行内表单
            saveButtonText: "保存",
          },
        },
      });
      // 对话框标题名称
      this.widgetFormData.editorOptions.config.title = data.cnName;
      this.configType = "WidgetConfig"; // 参数设置组件类型
      this.widgetFormSelect = null; // 编辑页面选中项
    },
    // 生成JSON
    handleGenerateJson() {
      this.jsonVisible = true;
      this.$nextTick(() => {
        // eslint-disable-next-line
        const editor = ace.edit("jsoneditor");
        editor.session.setMode("ace/mode/jsx");
      });
    },
    // 生成文件
    createBaseVue(type) {
      if (!this.moduleNode.bI_Id) {
        this.$message.error("请选择模块后再执行保存操作！");
        return;
      }
      let vueData = null;
      if (type === "jsoneditor") {
        // eslint-disable-next-line
        const editor = ace.edit("jsoneditor");
        vueData = editor.getSelectedText();
      }

      const node = this.moduleNode;
      // UI布局参数
      if (!vueData) {
        vueData = JSON.stringify(this.widgetFormData, null, 2);
      } else {
        this.widgetFormData = JSON.parse(vueData);
      }
      if (!vueData) {
        this.$message.error("没有可保存的数据！");
        return;
      }
      // 更新节点数据
      node.vueData = vueData;
      this.widgetFormData.dataOptions.bI_Id = this.moduleNode.bI_Id;
      this.widgetFormData.dataOptions.vueDataName = node.label; // 节点名称

      this.createLoading = true;
      const menu_Id = this.widgetFormData.dataOptions.menu_Id;
      var url = "/api/sys/bi/saveSearchData";
      const params = {
        noDataSign: true, // 数据不参与签名
        bI_Id: this.moduleNode.bI_Id,
        vueData: vueData,
        vueDataName: node.label,
        userProduct_Id: node.userProduct_Id,
        menu_Id: menu_Id,
      };

      this.common.ajax(
        url,
        params,
        (res) => {
          if (res.result) {
            this.$message.success(res.msg);
            this.moduleNode.vueData = vueData; // 保存数下拉框中的VueData
            this.jsonVisible = false;
          } else {
            this.$message({
              showClose: true,
              duration: 6000,
              message: res.msg,
              type: "error",
            });
          }
          this.createLoading = false;
          this.currentDialogVisible = false;
        },
        true
      );
    },
  },
};
</script>

<style lang="scss" scoped>
@import "./styles/index.scss";
.content {
  ::v-deep .el-tabs__header {
    margin: 0 0 2px;
  }
}
.param-header {
  padding: 0 5px !important;
}
.tree-popover {
  padding: 0 0px !important;
}
.module-item {
  margin-right: 20px;
  margin-bottom: 10px;
  color: #0885ce !important;
}

.widget-config-container {
  position: relative;

  .el-header {
    border-bottom: solid 2px #e4e7ed;
    padding: 0px;
  }

  .config-tab {
    height: 45px;
    line-height: 45px;
    display: inline-block;
    width: 145px;
    text-align: center;
    font-size: 14px;
    font-weight: 500;
    position: relative;
    cursor: pointer;

    &.active {
      border-bottom: solid 2px $primary-color;
    }
  }

  .config-content {
    padding: 0px !important;
    overflow: hidden;

    .el-form-item__label {
      padding: 0;
      font-weight: 500;
    }

    .el-form-item {
      // border-bottom: solid 1px #e1e1e1;
      padding-bottom: 0px;
      margin-bottom: 5;
    }
  }

  .ghost {
    background: #fff;
    border: 1px dashed $primary-color;

    &::after {
      background: #fff;
      display: block;
      content: "";
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
    }
  }

  ul {
    margin: 0;
    padding: 0;
  }

  li.ghost {
    list-style: none;
    font-size: 0;
    display: block;
    position: relative;
  }

  ::v-deep .config.scrollbar-wrap {
    max-height: 780px;
    overflow-x: hidden;
    padding: 10px;
  }

  @media (max-height: 750px) {
    ::v-deep .config.scrollbar-wrap {
      max-height: 600px;
    }
  }
}
</style>
